package com.base.tree;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspWriter;

public abstract class Tree {
	
	public static final String rootNodeId = "@root@id@";
	
	private boolean showRoot = true; // 显示根节点
	
	private boolean openFirstNode = false; // 是否展开第一个节点
	
	private TreeEventManager eventMgr = new TreeEventManager();
	
	private String Id = "";// 实例标识，后台使用
	
	private String containerId = "";// 前台div
	
	private TreeRender render = null;
	
	private TreeNode rootNode = new TreeNode(rootNodeId, "root", false);
	
	private boolean showLeafIcon = false;// 是否显示叶子节点展开收缩图标 
	
	private String imgHomeDir = "img/satantree/";
	
	private String default_click_event = "default_click";
	
	private TreeStyleType style = TreeStyleType.Style1;
	
	
	// 树节点再render时添加
	Map<String, TreeNode> nodes = new HashMap<String, TreeNode>();
	
	public Tree(String containerId) {
		this.containerId = containerId;
		render = new TreeRender(this);
		this.nodes.put(rootNode.getId(), rootNode);
		
		// 默认注册一个点击事件
		this.eventMgr.registerEvent(new TreeEvent(default_click_event, TreeEventType.click));
	}
	
	/**
	 * 注册事件
	 * @param eventName 事件名称
	 * @param type 事件类型
	 */
	public void registerEvent(String eventName, TreeEventType type) {
		this.registerEvent(new TreeEvent(eventName, type));
	}
	
	/**
	 * 注册事件
	 * @param event 事件对象
	 */
	public void registerEvent(TreeEvent event){
		eventMgr.registerEvent(event);
	}
	
	/**
	 * 删除事件
	 * @param eventID 事件标示
	 * @return 已删除的事件
	 */
	public TreeEvent removeEvent(String eventID) {
		return eventMgr.removeEvent(eventID);
	}
	
	/**
	 * 删除事件
	 * @param event 需删除的事件
	 * @return 是否成功删除
	 */
	public boolean removeEvent(TreeEvent event) {
		return eventMgr.removeEvent(event);
	}
	
	/**
	 * 删除所有事件
	 */
	public void removeAllEvents() {
		eventMgr.removeAllEvents();
	}
	
	public boolean isShowRoot() {
		return showRoot;
	}

	public void setShowRoot(boolean showRoot) {
		this.showRoot = showRoot;
	}
	
	public void addChildNodes(String pid, List<TreeNode> childNodes) {
		
		TreeNode pNode = nodes.get(pid);
		
		if(pNode == null) {
			return;
		}
		
		for(TreeNode node : childNodes) {
			node.setShowLeafIcon(this.showLeafIcon);
			node.setImgHomeDir(this.imgHomeDir);
			
			if(node.getStyle() == null) {
				node.setStyle(TreeNodeStyleType.getType(this.style.getValue()));
			}
			
			this.nodes.put(node.getId(), node);
			pNode.addChild(node);
		}
	}
	
	public TreeNode getNode(String id) {
		return nodes.get(id);
	}
	
	/**
	 * 获取下级节点
	 * @return 下级节点
	 */
	public abstract List<TreeNode> getNodes(String pid);
	
	// 初始化
	public void view(JspWriter out) {
		StringBuffer html = new StringBuffer(); 
		html.append(this.render.initView());
		try {
			out.print(html.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public String view(String pid) {
		String html = "";
		html = render.doView(pid).toString();
		return html;
	}

	public boolean isOpenFirstNode() {
		return openFirstNode;
	}

	public void setOpenFirstNode(boolean openFirstNode) {
		this.openFirstNode = openFirstNode;
	}

	public String getContainerId() {
		return containerId;
	}

	public void setContainerId(String containerId) {
		this.containerId = containerId;
	}

	public String getId() {
		return Id;
	}

	public void setId(String id) {
		Id = id;
	}

	public TreeEventManager getEventMgr() {
		return eventMgr;
	}

	public boolean isShowLeafIcon() {
		return showLeafIcon;
	}
	
	/**
	 * 是否显示叶子节点展开收缩图标
	 * @param showLeafIcon
	 */
	public void setShowLeafIcon(boolean showLeafIcon) {
		this.showLeafIcon = showLeafIcon;
	}

	public String getImgHomeDir() {
		return imgHomeDir;
	}

	public void setImgHomeDir(String imgHomeDir) {
		this.imgHomeDir = imgHomeDir;
	}

	public TreeStyleType getStyle() {
		return style;
	}

	public void setStyle(TreeStyleType style) {
		this.style = style;
	}
}
